package com.maxmlr.music.admin.service.impl;

import cn.hutool.core.util.StrUtil;
import com.baomidou.mybatisplus.core.toolkit.Wrappers;
import com.google.common.collect.Lists;
import com.maxmlr.music.admin.dao.DeptMapper;
import com.maxmlr.music.admin.dao.UserMapper;
import com.maxmlr.music.admin.dao.UserRoleMapper;
import com.maxmlr.music.admin.entity.Dept;
import com.maxmlr.music.admin.entity.User;
import com.maxmlr.music.admin.entity.UserRole;
import com.maxmlr.music.admin.param.UserParam;
import com.maxmlr.music.admin.service.UserService;
import com.maxmlr.music.admin.service.transfer.UserTransfer;
import com.maxmlr.music.common.base.BaseServiceImpl;
import com.maxmlr.music.common.exception.XmlrException;
import lombok.extern.slf4j.Slf4j;
import org.apache.commons.lang3.StringUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

import java.io.Serializable;
import java.util.List;
import java.util.Objects;
import java.util.Optional;
import java.util.stream.Collectors;

/**
 * @author max
 * @version 1.0
 * @ClassName UserServiceImpl
 * @Description 服务实现类
 * @Copyright Copyright (c) 2020: www.maxmlr.com.
 * @since 2020-06-14
 */
@Slf4j
@Service
public class UserServiceImpl extends BaseServiceImpl<UserMapper, User> implements UserService {

    @Autowired
    private UserRoleMapper userRoleMapper;

    @Autowired
    private DeptMapper deptMapper;

    @Autowired
    private UserTransfer userTransfer;

    @Override
    public User transferInParam(User user) {
        if (StringUtils.isBlank(user.getName())) {
            user.setName(null);
        }
        if (Objects.isNull(user.getDeptId()) || user.getDeptId() < 1) {
            user.setDeptId(null);
        }
        return user;
    }

    @Override
    public User getAdminUser() {
        return getById(1);
    }


    @Override
    @Transactional(rollbackFor = Exception.class)
    public boolean saveParam(UserParam param) {
        User user = userTransfer.po2User(param, getAdminUser());
        save(user);
        List<UserRole> userRoles = userTransfer.po2UserRole(param.getRoleIds(), user.getId());
        userRoles.forEach(userRoleMapper::insert);
        return true;
    }

    @Override
    public UserParam getUserParamById(Serializable id) {
        User user = getById(id);
        if (Objects.isNull(user)) {
            return new UserParam();
        }
        UserParam userParam = userTransfer.po2UserParam(user);
        if (Objects.nonNull(user.getDeptId())) {
            Dept dept = deptMapper.selectById(user.getDeptId());
            if (Objects.nonNull(dept)) {
                userParam.setDeptName(dept.getName());
            }
        }

        String roleIds = Optional.ofNullable(userRoleMapper.selectList(
                Wrappers.<UserRole>lambdaQuery().eq(UserRole::getUserId, user.getId())))
                .orElse(Lists.newArrayList())
                .stream()
                .map(UserRole::getRoleId)
                .map(String::valueOf)
                .collect(Collectors.joining(StrUtil.COMMA));
        userParam.setRoleIds(roleIds);
        return userParam;
    }

    @Override
    @Transactional(rollbackFor = Exception.class)
    public boolean updateParam(UserParam param) {
        User user = getById(param.getId());
        if (Objects.isNull(user)) {
            throw new XmlrException("用户为空！");
        }
        userTransfer.fullUser(user, param, getAdminUser());
        updateById(user);
        List<UserRole> userRoles = userTransfer.po2UserRole(param.getRoleIds(), user.getId());
        userRoleMapper.delete(Wrappers.<UserRole>lambdaQuery().eq(UserRole::getUserId, user.getId()));
        userRoles.forEach(userRoleMapper::insert);
        return true;
    }

    @Override
    public boolean updateUserPwd(UserParam param) {
        User user = getById(param.getId());
        if (Objects.isNull(user)) {
            throw new XmlrException("用户为空！");
        }
        userTransfer.fullUserPwd(user, param, getAdminUser());
        return updateById(user);
    }
}
